/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.contexts;

import cn.easyplatform.messages.vos.AuthorizationVo;
import cn.easyplatform.messages.vos.EnvVo;
import cn.easyplatform.messages.vos.LoginVo;
import cn.easyplatform.type.Constants;
import cn.easyplatform.web.task.event.EventListenerHandler;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.EventQueue;
import org.zkoss.zk.ui.event.EventQueues;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public abstract class Contexts {

    private static final ThreadLocal<Map<Class<?>, Object>> resources = new ThreadLocal<Map<Class<?>, Object>>() {
        @Override
        protected Map<Class<?>, Object> initialValue() {
            return new HashMap<Class<?>, Object>();
        }
    };

    public static final String PLATFORM_APP_ENV = "$easyplatformEnv";

    public static final String PLATFORM_USER_AUTHORIZATION = "$ueasyplatformUserAuthorization";

    public static final String PLATFORM_USER_ORGS = "$easyplatformOrgs";

    public static final String PLATFORM_USER = "$easyplatformUser";

    public static final String ANONYMOUS_TASKS = "$anonymous";

    /**
     * 发布信息
     *
     * @param data
     */
    public final static void publish(String name, Object data) {
        EventQueue<Event> que = EventQueues.lookup(name,
                EventQueues.DESKTOP, true);
        que.publish(new Event(name, null, data));
    }

    /**
     * 订阅信息
     *
     * @param evt
     */
    public final static void subscribe(String name, EventListener<Event> evt) {
        EventQueue<Event> que = EventQueues.lookup(name,
                EventQueues.DESKTOP, true);
        que.subscribe(evt);
    }

    /**
     * 退订信息
     *
     * @param evt
     */
    public final static void unsubscribe(String name, EventListener<Event> evt) {
        EventQueue<Event> que = EventQueues.lookup(name,
                EventQueues.DESKTOP, false);
        if (que != null)
            que.unsubscribe(evt);
    }

    /**
     * 通过request获取环境变量
     *
     * @param req
     * @return
     */
    public final static EnvVo getEnv(HttpServletRequest req) {
        return (EnvVo) req.getSession().getAttribute(PLATFORM_APP_ENV);
    }

    /**
     * @return
     */
    public final static EnvVo getEnv() {
        if (Sessions.getCurrent() == null)
            return null;
        return (EnvVo) Sessions.getCurrent().getAttribute(PLATFORM_APP_ENV);
    }

    /**
     * @param session
     * @return
     */
    public final static EnvVo getEnv(HttpSession session) {
        return (EnvVo) session.getAttribute(PLATFORM_APP_ENV);
    }

    /**
     * @param session
     * @return
     */
    public final static LoginVo getUser(HttpSession session) {
        return (LoginVo) session.getAttribute(PLATFORM_USER);
    }

    /**
     * @return
     */
    public final static AuthorizationVo getUserAuthorzation() {
        if (Sessions.getCurrent() == null)
            return null;
        return (AuthorizationVo) Sessions.getCurrent().getAttribute(
                PLATFORM_USER_AUTHORIZATION);
    }

    /**
     * @return
     */
    public final static LoginVo getUser() {
        if (Sessions.getCurrent() != null)
            return (LoginVo) Sessions.getCurrent().getAttribute(PLATFORM_USER);
        return null;
    }

    /**
     * Desktop Scope
     *
     * @return
     */
    public static DesktopContext getDesktop() {
        return new DesktopContext(Executions.getCurrent().getDesktop());
    }

    /**
     * 获取当前会话id
     *
     * @return
     */
    public static Serializable getSessionId() {
        return (Serializable) Sessions.getCurrent().getAttribute(Constants.SESSION_ID);
    }

    /**
     * Event Scope
     */
    public static void setEvent(Class<?> clazz, Event inst) {
        List<Event> events = (List<Event>) resources.get().get(Event.class);
        if (events == null) {
            events = new ArrayList<>();
            resources.get().put(clazz, events);
        }
        events.add(inst);
    }

    public static Event getEvent() {
        List<Event> events = (List<Event>) resources.get().get(Event.class);
        if (events != null && !events.isEmpty())
            return events.get(events.size() - 1);
        return null;
    }

    public static void setEventListenerHandler(EventListenerHandler elh) {
        resources.get().put(EventListenerHandler.class, elh);
    }

    public static EventListenerHandler getEventListenerHandler() {
        return (EventListenerHandler) resources.get().get(EventListenerHandler.class);
    }

    public static void clear() {
        List<Event> events = (List<Event>) resources.get().get(Event.class);
        if (events != null && !events.isEmpty()) {
            events.remove(events.size() - 1);
            if (events.isEmpty()) {
                events = null;
                resources.remove();
            }
        } else
            resources.remove();
    }
}
